//
//  vbo_vao_glsl.cpp
//  GLDemo
//
//  Created by wenqi on 5/23/14.
//  Copyright (c) 2014 xiewneqi. All rights reserved.
//

#include <stdio.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#else
#include "GL/glew.h"  // must come before the other GL includes
#include <GL/glut.h>
#endif

#include "shader_initialize.h"
#include "vbo_vao_glsl.h"

static float vertices[3][3] =
{
    {0, 0, -0.5},
    {0, 1, -0.5},
    {1, 0, -0.5}
};
static float color[3][3] =
{
    {1, 0, 0},
    {0, 1, 0},
    {0, 0, 0}
};

static float another_vertices [3][3] =
{
    {0.5, 0.5, 0.5},
    {0, -1, 0.5},
    {-1, 0, 0.5}
};
static float another_color[3][3] =
{
    {1, 0, 0},
    {0, 1, 0},
    {0, 0, 0}
};

static GLuint vbos[2];
static GLuint vaos[2];


void init_vbo_vao_glsl_main (int argc, char** argv)
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (800, 600);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Hello, VBO and VAO with GLSL");
    glutDisplayFunc (display_vbo_vao_glsl);
    init_vbo_vao_glsl_gl ();
    glutMainLoop ();

}

void init_vbo_vao_glsl_gl ()
{
    glClearDepth (0);
    glEnable (GL_DEPTH_TEST);
    glDepthFunc (GL_GEQUAL);
    glClearColor (1, 1, 1, 1);
    
    // 编译shader
    GLuint shaderProgram = InitShader ("vbo_vao_vertex_shader.glsl", "vbo_vao_fragment_shader.glsl");
    glUseProgram (shaderProgram);
    GLuint posLoc = glGetAttribLocation (shaderProgram, "va_position");
    GLuint colorLoc = glGetAttribLocation (shaderProgram, "va_color");
    
    glGenBuffers (2, vbos);
    glGenVertexArrays (2, vaos);
    
    // 设置第一个三角形的vbo，只是向显卡传递了数据，但是OPENGL并不知道这些数据哪些是
    // 顶点，哪些是颜色，哪些是法向量，哪些是UV等等，数据的用途通过与vbo绑定的vao提供
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertices) + sizeof (color), NULL, GL_STATIC_DRAW);
    glBufferSubData (GL_ARRAY_BUFFER, 0, sizeof (vertices), vertices);
    glBufferSubData (GL_ARRAY_BUFFER, sizeof (vertices), sizeof (color), color);
    
    // 设置第二个三角形的vbo
    glBindBuffer (GL_ARRAY_BUFFER, vbos[1]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (another_vertices) + sizeof (another_color), NULL, GL_STATIC_DRAW);
    glBufferSubData (GL_ARRAY_BUFFER, 0, sizeof (another_vertices), another_vertices);
    glBufferSubData (GL_ARRAY_BUFFER, sizeof (another_vertices), sizeof (another_color), another_color);
    
    // 创建vao，并绑定相应的数据段
    // 第一个三角形和vao/vbo绑定
    glBindVertexArray (vaos[0]);
    glEnableVertexAttribArray (posLoc);
    glEnableVertexAttribArray (colorLoc);
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glVertexAttribPointer (posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribPointer (colorLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*) sizeof(vertices));
    
    // 第二个三角形和vao/vbo绑定
    glBindVertexArray (vaos[1]);
    glBindBuffer (GL_ARRAY_BUFFER, vbos[1]);
    glEnableVertexAttribArray (posLoc);
    glVertexAttribPointer (posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray (colorLoc);
    glVertexAttribPointer (colorLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*) sizeof(another_vertices));
    
}

void display_vbo_vao_glsl ()
{
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // 绘制第一个三角形
    glBindVertexArray (vaos[0]);
    glDrawArrays (GL_TRIANGLES, 0, 3);
    
    // 绘制第二个三角形
    glBindVertexArray (vaos[1]);
    glDrawArrays (GL_TRIANGLES, 0, 3);
    
    glFlush ();

}